home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 October: Mac OS SDK / Dev.CD Oct 00 SDK1.toast / Development Kits / Mac OS / Multiprocessing 2.1v2 SDK / Sample Code / MP Sort Picts 12⁄04⁄99 / sources / MPBlitter.c next >
Encoding:
C/C++ Source or Header  |  1999-12-04  |  7.8 KB  |  307 lines  |  [TEXT/CWIE]

  1. /*
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    MPBlitter a simple blitter for MP Tasks. 
  5. **
  6. **    by Matthew Xavier Mora, Apple Developer Technical Support
  7. **
  8. **    File:        MPBlitter.c
  9. **
  10. **    Copyright © 1996-1997 Apple Computer, Inc.
  11. **    All rights reserved.
  12. **
  13. **    You may incorporate this sample code into your applications without
  14. **    restriction, though the sample code has been provided "AS IS" and the
  15. **    responsibility for its operation is 100% yours.  However, what you are
  16. **    not permitted to do is to redistribute the source as "DSC Sample Code"
  17. **    after having made changes. If you're going to re-distribute the source,
  18. **    we require that you make it clear in the source that the code was
  19. **    descended from Apple Sample Code, but that you've made changes.
  20. */
  21.  
  22. /* 
  23.     This is a simple blitter to allow my MPtask to blit to the screen.
  24.     I was going to add masked blitting that honored the visRgn and clip
  25.     regions so that it didn't color outside the lines. I haven't done that 
  26.     yet. 
  27.  
  28.     Since the original SortPicts program that I used only works with 
  29.       8 bit images I didn't spend any time adding any other cases to the 
  30.     blitter. If I ever get time I'll finish the blitter to be more useful
  31.     as a generic CopyBits routine for MP.
  32.  
  33. */
  34.  
  35. #include "MPBlitter.h"
  36. #include <Multiprocessing.h>
  37. //#include "MyInterruptSafeDebug.h"
  38. //-----------------------------------------------------------------------------------
  39. pascal void MPCopyBits(BitMapPtr srcBits, BitMapPtr dstBits,const Rect *srcRect,const Rect *dstRect,const short mode,const RgnHandle mask)
  40. //-----------------------------------------------------------------------------------
  41. {
  42. #pragma unused (mode)
  43.     PixMapPtr            srcPM;
  44.     PixMapPtr            dstPM;
  45.     long                dstLeft;
  46.     long                dstRight;
  47.     long                srcLeft;
  48.     long                srcRowBytes;
  49.     long                dstRowBytes;
  50.     char *                srcRow;
  51.     char *                dstRow;
  52.     char *                srcPtr;
  53.     char *                dstPtr;
  54.     long                 height;
  55.     long                width;
  56.     long                 i;
  57.     long                offset;
  58.     MPCriticalRegionID    blitterBusy;
  59.     
  60.     //  mask better contain a MPCriticalRegionID instead of a mask region handle!
  61.     blitterBusy = (MPCriticalRegionID)mask;
  62.     (void)MPEnterCriticalRegion(blitterBusy, kDurationForever);
  63.  
  64.     if (dstRect->top == dstRect->bottom) {
  65.         // a simple flag to say that the image is not ready
  66.         goto exit;
  67.     }
  68.     
  69.     srcPM = (PixMapPtr) srcBits;
  70.     dstPM = (PixMapPtr) dstBits;
  71.      
  72.     srcRow = (char *) srcPM->baseAddr;
  73.     dstRow = (char *) dstPM->baseAddr;
  74.  
  75.     srcRowBytes = (srcPM->rowBytes & 0x3fff);
  76.     dstRowBytes = (dstPM->rowBytes & 0x3fff);
  77.  
  78.     // get the bit offset to the src left edge
  79.     srcLeft = srcRect->left - srcPM->bounds.left;
  80.     srcLeft *= srcPM->pixelSize;
  81.     srcRow += srcLeft;
  82.  
  83.     // get the bit offset to the dst left and right edges
  84.     dstLeft = dstRect->left - dstPM->bounds.left;
  85.     dstLeft *= dstPM->pixelSize;
  86.     dstRight = dstRect->right - dstPM->bounds.left;
  87.     dstRight *= dstPM->pixelSize;
  88.     dstRow += dstLeft >> 3;
  89.         
  90.     // offset the src and dst ptrs to the first row
  91.     offset = srcRect->top - srcPM->bounds.top;
  92.     offset *= srcRowBytes  ;
  93.     srcRow += offset;
  94.  
  95.     offset = dstRect->top - dstPM->bounds.top;
  96.     offset *= dstRowBytes ;
  97.     dstRow += offset;
  98.  
  99.     height = dstRect->bottom - dstRect->top - 1;
  100.     width = dstRect->right - dstRect->left - 1;
  101.     width *= (dstPM->pixelSize >> 3);
  102.  
  103.     if (srcPM->pixelSize != dstPM->pixelSize) {
  104.         // ACK!
  105.         //InterruptSafeDebug ("\pPixel depth needs to be 8 bits! \n");
  106.         
  107.     }
  108.     switch (dstPM->pixelSize) {
  109.         case 8:
  110.             while (height--) {
  111.                 srcPtr = srcRow;
  112.                 dstPtr = dstRow;
  113.                 
  114.                 for (i = 0 ;i < width >> 2;i++) 
  115.                 {
  116.                     *dstPtr  = *srcPtr;
  117.                     ++srcPtr;
  118.                     ++dstPtr;
  119.                     *dstPtr  = *srcPtr;
  120.                     ++srcPtr;
  121.                     ++dstPtr;
  122.                     
  123.                     *dstPtr  = *srcPtr;
  124.                     ++srcPtr;
  125.                     ++dstPtr;
  126.                     
  127.                     *dstPtr  = *srcPtr;
  128.                     ++srcPtr;
  129.                     ++dstPtr;                            
  130.                 }
  131.  
  132.                 switch ( width % 4) {
  133.                     case 3:
  134.                         *dstPtr  = *srcPtr;
  135.                         ++srcPtr;
  136.                         ++dstPtr;                    
  137.                     case 2:
  138.                         *dstPtr  = *srcPtr;
  139.                         ++srcPtr;
  140.                         ++dstPtr;                    
  141.                     case 1:
  142.                         *dstPtr  = *srcPtr;
  143.                         ++srcPtr;
  144.                         ++dstPtr;
  145.                 }
  146.                 srcRow +=  srcRowBytes;
  147.                 dstRow +=  dstRowBytes;
  148.             }
  149.             break;
  150.         case  16:
  151.             break;
  152.         case 32:
  153.             break;
  154.     }
  155.     
  156. exit:
  157.     (void)MPExitCriticalRegion(blitterBusy);
  158. }
  159.  
  160.  
  161. static pascal void CopyBlit(PixMapPtr srcPM, PixMapPtr dstPM, Rect *srcRect, Rect *dstRect)
  162. {
  163.     long            dstLeft;
  164.     long            dstRight;
  165.     long *            srcRow;
  166.     long *            dstRow;
  167.     register long *    srcPtr;
  168.     register long *    dstPtr;
  169.     long            leftMask;
  170.     long            notLeftMask;
  171.     long            rightMask;
  172.     long            notRightMask;
  173.     long            dstLong;
  174.     short            dstLongs;
  175.     short            localheight;// = height;
  176.     long            offset;
  177.     long            timesCopy;
  178.     
  179.      short            height;
  180.      long            srcRowBytes;
  181.      long            dstRowBytes;
  182.      long            srcLeft;
  183.  
  184.     localheight = height = srcRect->bottom - srcRect->top;    // No scaling allowed
  185.     
  186.     srcRowBytes = srcPM->rowBytes & 0x3fff;
  187.     dstRowBytes = dstPM->rowBytes & 0x3fff;
  188.     
  189.     // get the bit offset to the src left edge
  190.     srcLeft = (srcRect->left - srcPM->bounds.left) * srcPM->pixelSize;
  191.  
  192.     srcRow = (long *) srcPM->baseAddr;
  193.     dstRow = (long *) dstPM->baseAddr;
  194.         
  195.     // offset the src ptr to the first long
  196.     srcRow += srcLeft >> 5;
  197.     
  198.     // get the bit offset to the dst left and right edges
  199.     dstLeft = (dstRect->left - dstPM->bounds.left) * dstPM->pixelSize;
  200.     dstRight = (dstRect->right - dstPM->bounds.left) * dstPM->pixelSize;
  201.     
  202.     // get the number of middle longs to do minus the left edge long
  203.     dstLongs = ((dstRight - dstLeft) >> 5) - 1;
  204.     
  205.     // offset the dst Ptr to the first long
  206.     dstRow += dstLeft >> 5;
  207.  
  208.     // now compute left and right masks for the dst
  209.     dstLeft &= 0x1f;
  210.     leftMask = ( 1 << dstLeft ) - 1;
  211.     notLeftMask = ~leftMask;
  212.     
  213.     dstRight &= 0x1f;
  214.     notRightMask = ( 1 << dstRight ) - 1;
  215.     rightMask = ~notRightMask;
  216.     
  217.     // offset the src and dst ptrs to the first row
  218.     offset = (srcRect->top - srcPM->bounds.top) * srcRowBytes;
  219.     srcRow +=  offset >> 2;
  220.     
  221.     offset = (dstRect->top - dstPM->bounds.top) * dstRowBytes;
  222.     dstRow +=  offset >>2;
  223.     
  224.     /* check if we need to do the left and right mask */
  225.     if ( leftMask )
  226.     {
  227.         if ( notLeftMask == 0 )
  228.         {
  229.             leftMask = 0;
  230.             dstLongs++;
  231.         }
  232.     }
  233.         
  234.     if ( rightMask )
  235.     {
  236.         if ( notRightMask == 0 )
  237.         {
  238.             rightMask = 0;
  239.             dstLongs++;
  240.         }
  241.     }
  242.         
  243.     //for ( ; localheight >= 0; --localheight )
  244.     // changing the above 'for()' to the below 'while()' is what made this blit routine
  245.     // faster than CopyBits - a speed improvement equal to all other changes I had made
  246.     // previously.  (about 4 to 5 milliseconds, in case you were wondering)
  247.     // Lesson: the true bottlenecks are not always the obvious ones
  248.     while (localheight--)
  249.     {
  250.         srcPtr = srcRow;
  251.         dstPtr = dstRow;
  252.         
  253.         /* do the masked left edge */
  254.         if ( leftMask )
  255.         {
  256.             dstLong = *srcPtr++ & leftMask;
  257.             dstLong |= *dstPtr & notLeftMask;
  258.             *dstPtr++ = dstLong;
  259.         }
  260.  
  261.         /* do the middle longs with Duff's device */
  262.         timesCopy = (dstLongs + 15) >> 4;
  263.         
  264.         switch( dstLongs & 0xF )
  265.         {
  266.             case 0:    do
  267.                 {        *dstPtr++ = *srcPtr++;
  268.             case 15:    *dstPtr++ = *srcPtr++;
  269.             case 14:    *dstPtr++ = *srcPtr++;
  270.             case 13:    *dstPtr++ = *srcPtr++;
  271.             case 12:    *dstPtr++ = *srcPtr++;
  272.             case 11:    *dstPtr++ = *srcPtr++;
  273.             case 10:    *dstPtr++ = *srcPtr++;
  274.             case 9:        *dstPtr++ = *srcPtr++;
  275.             case 8:        *dstPtr++ = *srcPtr++;
  276.             case 7:        *dstPtr++ = *srcPtr++;
  277.             case 6:        *dstPtr++ = *srcPtr++;
  278.             case 5:        *dstPtr++ = *srcPtr++;
  279.             case 4:        *dstPtr++ = *srcPtr++;
  280.             case 3:        *dstPtr++ = *srcPtr++;
  281.             case 2:        *dstPtr++ = *srcPtr++;
  282.             case 1:        *dstPtr++ = *srcPtr++;
  283.                 } while( --timesCopy > 0 );
  284.             }
  285.  
  286.         /* do the masked right edge */
  287.         if ( rightMask )
  288.         {
  289.             dstLong = *srcPtr & rightMask;
  290.             dstLong |= *dstPtr & notRightMask;
  291.             *dstPtr = dstLong;
  292.         }
  293.         
  294.         /* bump to the next row */
  295.         srcRow +=  srcRowBytes >>2;
  296.         dstRow +=  dstRowBytes >>2;
  297.     }        
  298. }
  299.  
  300. static pascal void betterMPCopyBits(BitMapPtr srcBits, BitMapPtr dstBits,
  301.                 Rect *srcRect, Rect *dstRect, 
  302.                 short mode, RgnHandle mask)
  303. {
  304. #pragma unused (mode,mask)
  305.      CopyBlit((PixMapPtr) srcBits, (PixMapPtr) dstBits,srcRect, dstRect);
  306. }
  307.